#include "EventLoopThreadPool.h"

EventLoopThreadPool::EventLoopThreadPool(EventLoop *loop, const std::string &name)
    : baseLoop_(loop),
      name_(name),
      nThread_(0),
      nextLoop_(0),
      started_(false)
{
}

void EventLoopThreadPool::start(int n, ThreadInitCallback cb)
{
    assert(!started_);
    baseLoop_->assertInLoopThread();
    started_ = true;
    nThread_ = n;
    for (int i = 0; i < nThread_; ++i)
    {
        threads_.push_back(std::make_unique<EventLoopThread>(name_ + std::to_string(i), cb));
        loops_.push_back(threads_[i]->startLoop());
    }
    if (nThread_ == 0 && cb)
    {
        cb(baseLoop_);
    }
}

EventLoopThreadPool::~EventLoopThreadPool()
{
    for (int i = 0; i < nThread_; ++i)
    {
        loops_[i]->quit();
    }
}

EventLoop *EventLoopThreadPool::getNextLoop()
{
    baseLoop_->assertInLoopThread();
    assert(started_);
    if (nThread_ > 0)
    {
        return loops_[nextLoop_++ % nThread_];
    }
    return baseLoop_;
}

std::vector<EventLoop *> EventLoopThreadPool::getAllLoops()
{
    baseLoop_->assertInLoopThread();
    assert(started_);
    if (nThread_ > 0)
    {
        return loops_;
    }
    else
    {
        return std::vector<EventLoop *>{baseLoop_};
    }
}
